home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / groupmod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-26  |  7.9 KB  |  420 lines

  1. /*
  2.  * Copyright 1991, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #ifndef lint
  13. static    char    sccsid[] = "@(#)groupmod.c    3.3    08:43:51    9/12/91";
  14. #endif
  15.  
  16. #include <sys/types.h>
  17. #include <stdio.h>
  18. #include <grp.h>
  19. #include <ctype.h>
  20. #include <fcntl.h>
  21.  
  22. #ifdef    BSD
  23. #include <strings.h>
  24. #else
  25. #include <string.h>
  26. #endif
  27.  
  28. #include "config.h"
  29. #include "shadow.h"
  30.  
  31. #ifdef    USE_SYSLOG
  32. #include <syslog.h>
  33. #endif
  34.  
  35. char    group_name[BUFSIZ];
  36. char    group_newname[BUFSIZ];
  37. int    group_id;
  38. int    group_newid;
  39.  
  40. char    *Prog;
  41.  
  42. int    oflg;    /* permit non-unique group ID to be specified with -g         */
  43. int    gflg;    /* new ID value for the group                                 */
  44. int    nflg;    /* a new name has been specified for the group                */
  45.  
  46. #ifdef    NDBM
  47. extern    int    gr_dbm_mode;
  48. extern    int    sg_dbm_mode;
  49. #endif
  50. extern    char    *malloc();
  51.  
  52. extern    struct    group    *getgrnam();
  53. extern    struct    group    *gr_next();
  54. extern    struct    group    *gr_locate();
  55. extern    int    gr_lock();
  56. extern    int    gr_unlock();
  57. extern    int    gr_rewind();
  58. extern    int    gr_open();
  59.  
  60. #ifdef    SHADOWGRP
  61. extern    struct    sgrp    *sgr_locate();
  62. extern    int    sgr_lock();
  63. extern    int    sgr_unlock();
  64. extern    int    sgr_open();
  65. #endif
  66.  
  67. /*
  68.  * usage - display usage message and exit
  69.  */
  70.  
  71. usage ()
  72. {
  73.     fprintf (stderr, "usage: groupmod [-g gid [-o]] [-n name] group\n");
  74.     exit (2);
  75. }
  76.  
  77. /*
  78.  * new_grent - updates the values in a group file entry
  79.  *
  80.  *    new_grent() takes all of the values that have been entered and
  81.  *    fills in a (struct group) with them.
  82.  */
  83.  
  84. void
  85. new_grent (grent)
  86. struct    group    *grent;
  87. {
  88.     if (nflg)
  89.         grent->gr_name = strdup (group_newname);
  90.  
  91.     if (gflg)
  92.         grent->gr_gid = group_newid;
  93. }
  94.  
  95. #ifdef    SHADOWGRP
  96. /*
  97.  * new_sgent - updates the values in a shadow group file entry
  98.  *
  99.  *    new_sgent() takes all of the values that have been entered and
  100.  *    fills in a (struct sgrp) with them.
  101.  */
  102.  
  103. void
  104. new_sgent (sgent)
  105. struct    sgrp    *sgent;
  106. {
  107.     if (nflg)
  108.         sgent->sg_name = strdup (group_newname);
  109. }
  110. #endif    /* SHADOWGRP */
  111.  
  112. /*
  113.  * grp_update - update group file entries
  114.  *
  115.  *    grp_update() writes the new records to the group files.
  116.  */
  117.  
  118. void
  119. grp_update ()
  120. {
  121.     struct    group    grp;
  122.     struct    group    *ogrp;
  123. #ifdef    SHADOWGRP
  124.     struct    sgrp    sgrp;
  125. #endif    /* SHADOWGRP */
  126.  
  127.     /*
  128.      * Create the initial entries for this new group.
  129.      */
  130.  
  131.     grp = *(gr_locate (group_name));
  132.     new_grent (&grp);
  133. #ifdef    SHADOWGRP
  134.     sgrp = *(sgr_locate (group_name));
  135.     new_sgent (&sgrp);
  136. #endif    /* SHADOWGRP */
  137.  
  138.     /*
  139.      * Write out the new group file entry.
  140.      */
  141.  
  142.     if (! gr_update (&grp)) {
  143.         fprintf (stderr, "%s: error adding new group entry\n", Prog);
  144.         exit (1);
  145.     }
  146.     if (nflg && ! gr_remove (group_name)) {
  147.         fprintf (stderr, "%s: error removing group entry\n", Prog);
  148.         exit (1);
  149.     }
  150. #ifdef    NDBM
  151.  
  152.     /*
  153.      * Update the DBM group file with the new entry as well.
  154.      */
  155.  
  156.     if (access ("/etc/group.pag", 0) == 0) {
  157.         if (! gr_dbm_update (&grp)) {
  158.             fprintf (stderr, "%s: cannot add new dbm group entry\n",
  159.                 Prog);
  160.             exit (1);
  161.         }
  162.         if (nflg && (ogrp = getgrnam (group_name)) &&
  163.                 ! gr_dbm_remove (ogrp)) {
  164.             fprintf (stderr, "%s: error removing group dbm entry\n",
  165.                 Prog);
  166.             exit (1);
  167.         }
  168.         endgrent ();
  169.     }
  170. #endif    /* NDBM */
  171.  
  172. #ifdef    SHADOWGRP
  173.  
  174.     /*
  175.      * Write out the new shadow group entries as well.
  176.      */
  177.  
  178.     if (! sgr_update (&sgrp)) {
  179.         fprintf (stderr, "%s: error adding new group entry\n", Prog);
  180.         exit (1);
  181.     }
  182.     if (nflg && ! sgr_remove (group_name)) {
  183.         fprintf (stderr, "%s: error removing group entry\n", Prog);
  184.         exit (1);
  185.     }
  186. #ifdef    NDBM
  187.  
  188.     /*
  189.      * Update the DBM shadow group file with the new entry as well.
  190.      */
  191.  
  192.     if (access ("/etc/gshadow.pag", 0) == 0) {
  193.         if (! sgr_dbm_update (&sgrp)) {
  194.             fprintf (stderr,
  195.                 "%s: cannot add new dbm shadow group entry\n",
  196.                 Prog);
  197.             exit (1);
  198.         }
  199.         if (nflg && ! sgr_dbm_remove (group_name)) {
  200.             fprintf (stderr,
  201.                 "%s: error removing shadow group dbm entry\n",
  202.                 Prog);
  203.             exit (1);
  204.         }
  205.         endsgent ();
  206.     }
  207. #endif    /* NDBM */
  208. #endif    /* SHADOWGRP */
  209. #ifdef    USE_SYSLOG
  210.     if (nflg)
  211.         syslog (LOG_INFO, "change group `%s' to `%s'\n",
  212.             group_name, group_newname);
  213.  
  214.     if (gflg)
  215.         syslog (LOG_INFO, "change gid for `%s' to %d\n",
  216.             nflg ? group_name:group_newname, group_newid);
  217. #endif    /* USE_SYSLOG */
  218. }
  219.  
  220. /*
  221.  * check_new_gid - check the new GID value for uniqueness
  222.  *
  223.  *    check_new_gid() insures that the new GID value is unique.
  224.  */
  225.  
  226. int
  227. check_new_gid ()
  228. {
  229.     /*
  230.      * First, the easy stuff.  If the ID can be duplicated, or if
  231.      * the ID didn't really change, just return.  If the ID didn't
  232.      * change, turn off those flags.  No sense doing needless work.
  233.      */
  234.  
  235.     if (oflg)
  236.         return 0;
  237.  
  238.     if (group_id == group_newid) {
  239.         gflg = 0;
  240.         return 0;
  241.     }
  242.     if (getgrgid (group_newid))
  243.         return -1;
  244.  
  245.     return 0;
  246. }
  247.  
  248. /*
  249.  * process_flags - perform command line argument setting
  250.  *
  251.  *    process_flags() interprets the command line arguments and sets
  252.  *    the values that the user will be created with accordingly.  The
  253.  *    values are checked for sanity.
  254.  */
  255.  
  256. void
  257. process_flags (argc, argv)
  258. int    argc;
  259. char    **argv;
  260. {
  261.     extern    int    optind;
  262.     extern    char    *optarg;
  263.     char    *end;
  264.     int    arg;
  265.  
  266.     while ((arg = getopt (argc, argv, "og:n:")) != EOF) {
  267.         switch (arg) {
  268.             case 'g':
  269.                 gflg++;
  270.                 group_newid = strtol (optarg, &end, 10);
  271.                 if (*end != '\0') {
  272.                     fprintf (stderr, "%s: invalid group %s\n",
  273.                         Prog, optarg);
  274.                     exit (3);
  275.                 }
  276.                 break;
  277.             case 'n':
  278.                 if (strcmp (group_name, optarg)) {
  279.                     nflg++;
  280.                     strncpy (group_newname, optarg, BUFSIZ);
  281.                 }
  282.                 break;
  283.             case 'o':
  284.                 if (! gflg)
  285.                     usage ();
  286.  
  287.                 oflg++;
  288.                 break;
  289.             default:
  290.                 usage ();
  291.         }
  292.     }
  293.     if (optind == argc - 1)
  294.         strcpy (group_name, argv[argc - 1]);
  295.     else
  296.         usage ();
  297. }
  298.  
  299. /*
  300.  * close_files - close all of the files that were opened
  301.  *
  302.  *    close_files() closes all of the files that were opened for this
  303.  *    new group.  This causes any modified entries to be written out.
  304.  */
  305.  
  306. close_files ()
  307. {
  308.     if (! gr_close ()) {
  309.         fprintf (stderr, "%s: cannot rewrite group file\n", Prog);
  310.         exit (1);
  311.     }
  312.     (void) gr_unlock ();
  313. #ifdef    SHADOWGRP
  314.     if (! sgr_close ()) {
  315.         fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  316.             Prog);
  317.         exit (1);
  318.     }
  319.     (void) sgr_unlock ();
  320. #endif    /* SHADOWGRP */
  321. }
  322.  
  323. /*
  324.  * open_files - lock and open the group files
  325.  *
  326.  *    open_files() opens the two group files.
  327.  */
  328.  
  329. open_files ()
  330. {
  331.     if (! gr_lock ()) {
  332.         fprintf (stderr, "%s: unable to lock group file\n", Prog);
  333.         exit (1);
  334.     }
  335.     if (! gr_open (O_RDWR)) {
  336.         fprintf (stderr, "%s: unable to open group file\n", Prog);
  337.         exit (1);
  338.     }
  339. #ifdef    SHADOWGRP
  340.     if (! sgr_lock ()) {
  341.         fprintf (stderr, "%s: unable to lock shadow group file\n",
  342.             Prog);
  343.         exit (1);
  344.     }
  345.     if (! sgr_open (O_RDWR)) {
  346.         fprintf (stderr, "%s: unable to open shadow group file\n",
  347.             Prog);
  348.         exit (1);
  349.     }
  350. #endif    /* SHADOWGRP */
  351. }
  352.  
  353. /*
  354.  * main - groupmod command
  355.  *
  356.  *    The syntax of the groupmod command is
  357.  *    
  358.  *    groupmod [ -g gid [ -o ]] [ -n name ] group
  359.  *
  360.  *    The flags are
  361.  *        -g - specify a new group ID value
  362.  *        -o - permit the group ID value to be non-unique
  363.  *        -n - specify a new group name
  364.  */
  365.  
  366. main (argc, argv)
  367. int    argc;
  368. char    **argv;
  369. {
  370.  
  371.     /*
  372.      * Get my name so that I can use it to report errors.
  373.      */
  374.  
  375.     if (Prog = strrchr (argv[0], '/'))
  376.         Prog++;
  377.     else
  378.         Prog = argv[0];
  379.  
  380. #ifdef    USE_SYSLOG
  381.     openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  382. #endif    /* USE_SYSLOG */
  383.  
  384.     /*
  385.      * The open routines for the DBM files don't use read-write
  386.      * as the mode, so we have to clue them in.
  387.      */
  388.  
  389. #ifdef    NDBM
  390.     gr_dbm_mode = O_RDWR;
  391. #ifdef    SHADOWGRP
  392.     sg_dbm_mode = O_RDWR;
  393. #endif    /* SHADOWGRP */
  394. #endif    /* NDBM */
  395.     process_flags (argc, argv);
  396.  
  397.     /*
  398.      * Start with a quick check to see if the group exists.
  399.      */
  400.  
  401.     if (! getgrnam (group_name)) {
  402.         fprintf (stderr, "%s: group %s does not exist\n",
  403.             Prog, group_name);
  404.         exit (9);
  405.     }
  406.  
  407.     /*
  408.      * Do the hard stuff - open the files, create the group entries,
  409.      * then close and update the files.
  410.      */
  411.  
  412.     open_files ();
  413.  
  414.     grp_update ();
  415.  
  416.     close_files ();
  417.     exit (0);
  418.     /*NOTREACHED*/
  419. }
  420.